package com.cspm.ahjy.bc.office.word.util;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.dom4j.Element;

import com.cspm.ahjy.bc.office.enums.AlignEnum;
import com.cspm.ahjy.bc.office.enums.ColorEnum;
import com.cspm.ahjy.bc.office.util.UnitConvertUtil;
import com.cspm.ahjy.bc.office.word.domain.MSAction;
import com.cspm.ahjy.bc.office.word.domain.MSActionType;
import com.cspm.ahjy.bc.office.word.domain.MSBorder;
import com.cspm.ahjy.bc.office.word.domain.MSTable;
import com.cspm.ahjy.bc.office.word.domain.MSTableAction;
import com.cspm.ahjy.bc.office.word.domain.MSTableCol;
import com.cspm.ahjy.bc.office.word.domain.MSTableRow;

/**
 * 表格工具类
 * 
 * @author ServerZhang
 * @date 2017年10月12日
 */
public class TableUtil {
	
	/**
	 * 解析<wx:sect>获取表格对象
	 * 
	 * @param sectElement
	 * @param path 文档所在目录 
	 * @return
	 * @author ServerZhang
	 * @date 2017年10月12日
	 */
	public static List<MSTable> getMsTables(Element sectElement, String path) {
		List<MSTable> msTables = new ArrayList<MSTable>();

		List<Element> tblE = sectElement.elements("tbl");

		Iterator<Element> iterator = tblE.iterator();
		while (iterator.hasNext()) {
			Element next = iterator.next();
			MSTable msTable = new MSTable();

			// 1.表格属性
			Element tblPr = next.element("tblPr");
			if (tblPr != null) {
				Element tblBorders = tblPr.element("tblBorders");
				if (tblBorders != null) {
					String topColor = null;
					String leftColor = null;
					String bottomColor = null;
					String rightColor = null;
					String insideHColor = null;
					String insideVColor = null;

					Element top = tblBorders.element("top");
					if (top != null) {
						MSBorder msBorder = BorderUtil.getMsBorder(top);
						topColor = msBorder.getColor();
						msTable.setTopBorder(msBorder);
					}
					Element left = tblBorders.element("left");
					if (left != null) {
						MSBorder msBorder = BorderUtil.getMsBorder(left);
						leftColor = msBorder.getColor();
						msTable.setLeftBorder(msBorder);
					}
					Element bottom = tblBorders.element("bottom");
					if (bottom != null) {
						MSBorder msBorder = BorderUtil.getMsBorder(bottom);
						bottomColor = msBorder.getColor();
						msTable.setBottomBorder(msBorder);
					}
					Element right = tblBorders.element("right");
					if (right != null) {
						MSBorder msBorder = BorderUtil.getMsBorder(right);
						rightColor = msBorder.getColor();
						msTable.setRightBorder(msBorder);
					}
					Element insideH = tblBorders.element("insideH");
					if (insideH != null) {
						MSBorder msBorder = BorderUtil.getMsBorder(insideH);
						insideHColor = msBorder.getColor();
						msTable.setInsideHBorder(msBorder);
					}
					Element insideV = tblBorders.element("insideV");
					if (insideV != null) {
						MSBorder msBorder = BorderUtil.getMsBorder(insideV);
						insideVColor = msBorder.getColor();
						msTable.setInsideVBorder(msBorder);
					}
					if (topColor != null && leftColor != null
							&& bottomColor != null && rightColor != null
							&& topColor.equals(leftColor)
							&& topColor.equals(bottomColor)
							&& topColor.equals(rightColor)) {
						msTable.setOutsideColor(topColor);
					}
					if (insideHColor != null && insideVColor != null
							&& insideHColor.equals(insideVColor)) {
						msTable.setInsideColor(insideHColor);
					}

				}
			}

			// 行
			List<Element> trE = next.elements("tr");
			Iterator<Element> trIterator = trE.iterator();
			List<MSTableRow> msRows = new ArrayList<MSTableRow>();

			Integer height = null;
			String heightRule = null;
			String alignType = null;
			String horizontalType = null;

			int index = 0;
			while (trIterator.hasNext()) {
				Element tr = trIterator.next();
				MSTableRow msTableRow = TableRowUtil.getMsTableRow(tr, path);
				msRows.add(msTableRow);
				if (index == 0) {
					height = msTableRow.getHeight();
				} else if (height != null) {
					if (!height.equals(msTableRow.getHeight())) {
						height = null;
					}
				}
				if (index == 0) {
					heightRule = msTableRow.getHeightRule();
				} else if (heightRule != null) {
					if (!heightRule.equals(msTableRow.getHeightRule())) {
						heightRule = null;
					}
				}
				if (index == 0) {
					alignType = msTableRow.getAlignType();
				} else if (alignType != null) {
					if (!alignType.equals(msTableRow.getAlignType())) {
						alignType = null;
					}
				}
				if (index == 0) {
					horizontalType = msTableRow.getHorizontalType();
				} else if (horizontalType != null) {
					if (!horizontalType.equals(msTableRow.getHorizontalType())) {
						horizontalType = null;
					}
				}

				index++;
			}

			msTable.setHeightRule(heightRule);
			msTable.setRowHeight(height);
			msTable.setAlignType(alignType);
			msTable.setHorizontalType(horizontalType);

			msTable.setMsTableRows(msRows);

			msTables.add(msTable);
		}

		return msTables;
	}

	/**
	 * 表格比较
	 * 
	 * @param table1
	 * @param table2
	 * @return
	 * @author ServerZhang
	 * @date 2017年10月12日
	 */
	public static List<MSAction> compare(MSTable table1, MSTable table2,
			Integer tableNo) {
		List<MSAction> actions = new ArrayList<MSAction>();

		String heightRule1 = table1.getHeightRule();
		String heightRule2 = table2.getHeightRule();
		if (heightRule2 != null && !heightRule2.equals(heightRule1)) {
			MSAction action = new MSAction();
			MSTableAction tableAction = new MSTableAction();
			MSActionType actionType = new MSActionType();

			tableAction.setTableNo(tableNo);
			actionType.setType("table_heightRule");
			actionType.setTypeValue(heightRule2);
			actionType.setTypeContent("每一行的行高值是 "
					+ ("exact".equals(heightRule2) ? "固定值" : "最小值"));

			tableAction.setMsActionType(actionType);
			action.setMsTableAction(tableAction);

			actions.add(action);
		}
		Integer rowHeight1 = table1.getRowHeight();
		Integer rowHeight2 = table2.getRowHeight();
		if (rowHeight2 != null && !rowHeight2.equals(rowHeight1)) {
			MSAction action = new MSAction();
			MSTableAction tableAction = new MSTableAction();
			MSActionType actionType = new MSActionType();
			tableAction.setTableNo(tableNo);
			actionType.setType("table_rowHeight");
			actionType.setTypeValue(rowHeight2);
			actionType.setTypeContent("每一行指定高度 "
					+ UnitConvertUtil.standar2CM(rowHeight2));

			tableAction.setMsActionType(actionType);
			action.setMsTableAction(tableAction);

			actions.add(action);
		}
		String outsideColor1 = table1.getOutsideColor();
		String outsideColor2 = table2.getOutsideColor();
		if (outsideColor2 != null && !outsideColor2.equals(outsideColor1)) {
			MSAction action = new MSAction();
			MSTableAction tableAction = new MSTableAction();
			MSActionType actionType = new MSActionType();
			tableAction.setTableNo(tableNo);
			actionType.setType("table_outsideColor");
			actionType.setTypeValue(outsideColor2);
			
			String content = "外框颜色为“";
			ColorEnum byValue = ColorEnum.getByValue(outsideColor2);
			if (byValue != null) {
				content += byValue.getName();
			}else {
				content += outsideColor2;
			}
			content += "”";
			
			actionType.setTypeContent(content);

			tableAction.setMsActionType(actionType);
			action.setMsTableAction(tableAction);

			actions.add(action);
		}
		String insideColor1 = table1.getInsideColor();
		String insideColor2 = table2.getInsideColor();
		if (insideColor2 != null && !insideColor2.equals(insideColor1)) {
			MSAction action = new MSAction();
			MSTableAction tableAction = new MSTableAction();
			MSActionType actionType = new MSActionType();
			tableAction.setTableNo(tableNo);
			actionType.setType("table_insideColor");
			actionType.setTypeValue(insideColor2);
			
			String content = "内框颜色为“";
			ColorEnum byValue = ColorEnum.getByValue(insideColor2);
			if (byValue != null) {
				content += byValue.getName();
			}else {
				content += insideColor2;
			}
			content += "”";
			
			actionType.setTypeContent(content);

			tableAction.setMsActionType(actionType);
			action.setMsTableAction(tableAction);

			actions.add(action);
		}
		String alignType1 = table1.getAlignType();
		String alignType2 = table2.getAlignType();
		if (alignType2 != null && !alignType2.equals(alignType1)) {
			MSAction action = new MSAction();
			MSTableAction tableAction = new MSTableAction();
			MSActionType actionType = new MSActionType();
			tableAction.setTableNo(tableNo);
			actionType.setType("table_alignType");
			actionType.setTypeValue(alignType2);
			
			String content = "内容垂直对齐方式为“";
			AlignEnum byValue = AlignEnum.getByValue(alignType2);
			if (byValue != null) {
				content += byValue.getText();
			}else {
				content += alignType2;
			}
			content += "”";
			
			actionType.setTypeContent(content);

			tableAction.setMsActionType(actionType);
			action.setMsTableAction(tableAction);

			actions.add(action);
		}
		String horizontalType1 = table1.getHorizontalType();
		String horizontalType2 = table2.getHorizontalType();
		if (horizontalType2 != null && !horizontalType2.equals(horizontalType1)) {
			MSAction action = new MSAction();
			MSTableAction tableAction = new MSTableAction();
			MSActionType actionType = new MSActionType();
			tableAction.setTableNo(tableNo);
			actionType.setType("table_horizontalType");
			actionType.setTypeValue(horizontalType2);
			
			String content = "内容水平对齐方式为“";
			AlignEnum byValue = AlignEnum.getByValue(horizontalType2);
			if (byValue != null) {
				content += byValue.getText();
			}else {
				content += horizontalType2;
			}
			content += "”";
			
			actionType.setTypeContent(content);

			tableAction.setMsActionType(actionType);
			action.setMsTableAction(tableAction);

			actions.add(action);
		}
		List<MSTableRow> msTableRows1 = table1.getMsTableRows();
		List<MSTableRow> msTableRows2 = table2.getMsTableRows();
		// 是否有行、列合并（不考虑行、列拆分）
		int size1 = msTableRows1.size();
		int size2 = msTableRows2.size();
		if (size1 == size2) {// 无行合并
			for (int i = 0; i < size1; i++) {
				MSTableRow msTableRow1 = msTableRows1.get(i);
				MSTableRow msTableRow2 = msTableRows2.get(i);
				List<MSTableCol> msTableCols1 = msTableRow1.getMsTableCols();
				List<MSTableCol> msTableCols2 = msTableRow2.getMsTableCols();
				int cSize1 = msTableCols1.size();
				int cSize2 = msTableCols2.size();
				if (cSize1 > cSize2) {// 存在列合并
					for (int j = 0; j < cSize2; j++) {
						MSTableCol msTableCol2 = msTableCols2.get(j);
						Integer width2 = msTableCol2.getWidth();
						Integer tempW = 0;// 累加列宽
						Integer tempK = j;// 默认同列开始循环，但如果已存在合并，下次循环从合并后的位置开始
						for (int k = tempK; k < cSize1; k++) {
							MSTableCol msTableCol1 = msTableCols1.get(k);
							Integer width1 = msTableCol1.getWidth();
							if (width1.equals(width2) && k == j) {// 列宽相等，且位于同一列，说明无合并，跳出循环
								tempW = 0;
								break;
							} else if (width2 > width1) { // 不等宽
								tempW += width1;
								if (width2.equals(tempW)) {// 累积宽度与合并后的宽度相等
									tempK = k + 1;// 记录当前合并的下一列位置
									tempW = 0;

									MSAction action = new MSAction();
									MSTableAction tableAction = new MSTableAction();
									MSActionType actionType = new MSActionType();
									tableAction.setTableNo(tableNo);
									actionType.setType("table_row_col_merge");
									actionType.setTypeValue(tableNo + "-"
											+ (i + 1) + "-(" + (j + 1) + "-"
											+ (k + 1) + ")");
									actionType.setTypeContent("第" + (i + 1)
											+ "行的第“" + (j + 1) + "-" + (k + 1)
											+ "”列合并");

									tableAction.setMsActionType(actionType);
									action.setMsTableAction(tableAction);

									actions.add(action);

									break;
								}
							} else {
								tempW = 0;
								continue;
							}
						}
					}
				}
			}

		} else {// TODO 有行合并

		}

		return actions;
	}

}
